home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
oper_sys
/
emerald
/
emrldsys.lha
/
Language
/
Compiler
/
em.ccompiler.y
< prev
next >
Wrap
Text File
|
1990-08-16
|
24KB
|
931 lines
%{
/*
* @(#)em.ccompiler.act 1.1 3/17/89
*/
#include <stdio.h>
#include "y.tab.h"
#include "error.h"
#include "tokens.h"
#include "nodes.h"
#include "keyword.h"
#include "sequence.h"
#include "semantics.h"
#define YYSTYPE NodePtr
extern NodePtr Root, buildString();
static int nextPhoney = 0;
%}
%start compilation
%token TIDENTIFIER /* "identifier" */
%token TOPERATOR /* "operator" */
%token TLPAREN /* "(" */
%token TRPAREN /* ")" */
%token TLSQUARE /* "[" */
%token TRSQUARE /* "]" */
%token TLCURLY /* "{" */
%token TRCURLY /* "}" */
%token TDOLLAR /* "$" */
%token TDOT /* "." */
%token TCOMMA /* "," */
%token TCOLON /* ":" */
%token TSUGARASSIGN /* ":=" */
%token TINTEGERLITERAL /* "integer" */
%token TREALLITERAL /* "real" */
%token TCHARACTERLITERAL /* "character" */
%token TSTRINGLITERAL /* "string" */
%token TEOF 0 /* "end of file" */
%token OAND /* "&" */
%token OASSIGN /* "<-" */
%token OCONFORMSTO /* "*>" */
%token ODIVIDE /* "/" */
%token OEQUAL /* "=" */
%token OGREATER /* ">" */
%token OGREATEREQUAL /* ">=" */
%token OIDENTITY /* "==" */
%token OLESS /* "<" */
%token OLESSEQUAL /* "<=" */
%token OMINUS /* "-" */
%token OMOD /* "#" */
%token ONEGATE /* "~" */
%token ONOT /* "!" */
%token ONOTEQUAL /* "!=" */
%token ONOTIDENTITY /* "!==" */
%token OOR /* "|" */
%token OPLUS /* "+" */
%token ORETURNS /* "->" */
%token OTIMES /* "*" */
%token KABSTRACTTYPE /* "abstracttype" */
%token KAND /* "and" */
%token KALL /* "all" */
%token KANY /* "any" */
%token KARRAY /* "array" */
%token KAS /* "as" */
%token KASSERT /* "assert" */
%token KAT /* "at" */
%token KAWAITING /* "awaiting" */
%token KATTACHED /* "attached" */
%token KBEGIN /* "begin" */
%token KBOOLEAN /* "boolean" */
%token KBY /* "by" */
%token KCHARACTER /* "character" */
%token KCHECKPOINT /* "checkpoint" */
%token KCONDITION /* "condition" */
%token KCONFIRM /* "confirm" */
%token KCONST /* "const" */
%token KDIRECT /* "direct" */
%token KDO /* "do" */
%token KELSE /* "else" */
%token KELSEIF /* "elseif" */
%token KEND /* "end" */
%token KENUMERATION /* "enumeration" */
%token KEXIT /* "exit" */
%token KEXPORT /* "export" */
%token KFAILURE /* "failure" */
%token KFALSE /* "false" */
%token KFIX /* "fix" */
%token KFOR /* "for" */
%token KFROM /* "from" */
%token KFUNCTION /* "function" */
%token KNONE /* "none" */
%token KOWNNAME /* "ownname" */
%token KOWNTYPE /* "owntype" */
%token KGLOBAL /* "global" */
%token KIF /* "if" */
%token KIMMUTABLE /* "immutable" */
%token KIMPORT /* "import" */
%token KINITIALLY /* "initially" */
%token KINTEGER /* "integer" */
%token KISFIXED /* "isfixed" */
%token KLOCAL /* "local" */
%token KLOCATE /* "locate" */
%token KLOOP /* "loop" */
%token KMONITOR /* "monitor" */
%token KMOVE /* "move" */
%token KNIL /* "nil" */
%token KNODE /* "node" */
%token KOBJECT /* "object" */
%token KON /* "on" */
%token KOP /* "op" */
%token KOPERATION /* "operation" */
%token KOR /* "or" */
%token KPRIMITIVE /* "primitive" */
%token KPRIVATE /* "private" */
%token KRESTRICT /* "restrict" */
%token KSIGNATURE /* "signature" */
%token KPROCESS /* "process" */
%token KREAL /* "real" */
%token KRECORD /* "record" */
%token KRECOVERY /* "recovery" */
%token KREFIX /* "refix" */
%token KRETURN /* "return" */
%token KRETURNANDFAIL /* "returnandfail" */
%token KSELF /* "self" */
%token KSIGNAL /* "signal" */
%token KSTRING /* "string" */
%token KTHEN /* "then" */
%token KTIME /* "time" */
%token KTO /* "to" */
%token KTRUE /* "true" */
%token KTYPE /* "type" */
%token KUNAVAILABLE /* "unavailable" */
%token KUNFIX /* "unfix" */
%token KUNION /* "union" */
%token KVAR /* "var" */
%token KVECTOR /* "vector" */
%token KVIEW /* "view" */
%token KVISIT /* "visit" */
%token KWAIT /* "wait" */
%token KWHEN /* "when" */
%token KWHILE /* "while" */
%token KWHERE /* "where" */
%right KAS KVIEW KTO KRESTRICT /* precedence, lowest first */
%left OOR KOR
%left OAND KAND
%left ONOT
%left OIDENTITY ONOTIDENTITY OEQUAL ONOTEQUAL OGREATER OLESS OGREATEREQUAL OLESSEQUAL OCONFORMSTO
%left OPLUS OMINUS
%left OTIMES ODIVIDE OMOD TOPERATOR
%left ONEGATE KISFIXED KLOCATE KAWAITING
%%
compilation :
environmentImportS environmentExportS constantDeclarationS
{ Root = Construct(P_COMP, 3, $1, $2, $3); }
;
constantDeclarationS :
constantDeclaration
{ $$ = RCONS(NULL, $1); }
| constantDeclarationS constantDeclaration
{ $$ = RCONS($1, $2); }
;
empty :
{ $$ = NULL; }
;
environmentImportS :
empty
| environmentImportS environmentImport
{ $$ = RCONS($1, $2); }
;
environmentImport :
KIMPORT symbolDefinitionS KFROM environmentPathName
{ $$= Construct(P_IMPORT, 2, $2, $4); }
;
environmentExportS :
empty
| environmentExportS environmentExport
{ $$ = RCONS($1, $2); }
;
environmentExport :
KEXPORT symbolReferenceS KTO environmentPathName
{ $$ = Construct(P_EXPORT, 2, $2, $4); }
;
environmentPathName :
TSTRINGLITERAL
;
typeClauseOpt :
empty
| typeClause
;
typeClause :
TCOLON typeDefinition
{ $$ = $2; }
;
typeDefinition :
invocation
;
builtinType :
/* taken care of where it is called, so $$ = $1 is ok. */
KABSTRACTTYPE
| KANY
| KARRAY
| KBOOLEAN
| KCHARACTER
| KCONDITION
| KINTEGER
| KNODE
| KNONE
| KSIGNATURE
| KREAL
| KSTRING
| KTIME
| KVECTOR
;
optVariable :
KVAR
| empty
;
abstractType :
KTYPE optVariable symbolDefinition operationSignatureS KEND symbolReference
{ Names_Check($3, $6);
if (($6) != NULL) free($6);
$$ = Construct(P_ATLIT, 4,
buildString(currentFileName), NULL, $3, $4);
($$)->b.atlit.f.isTypeVariable = ($2 != NULL); }
;
record :
KRECORD symbolDefinition recordFieldS KEND symbolReference
{ Names_Check($2, $5);
if (($5) != NULL) free($5);
$$ = Construct(P_RECORDLIT, 2, $2, $3); }
;
recordFieldS :
recordField
{ $$ = RAPPEND(NULL, $1); }
| recordFieldS recordField
{ $$ = RAPPEND($1, $2); }
;
recordField :
KVAR symbolDefinitionS typeClause
{ $$ = Distribute(P_VARDECL, $2, 2, $3, NULL); }
| KATTACHED KVAR symbolDefinitionS typeClause
{ $$ = Distribute(P_VARDECL, $3, 2, $4, NULL);
{
register NodePtr q;
if (($$)->tag == T_SEQUENCE) {
Sequence_For(q, ($$))
q->b.vardecl.isAttached = TRUE;
Sequence_Next
} else {
($$)->b.vardecl.isAttached = TRUE;
}
}
}
;
union :
KUNION symbolDefinition recordFieldS KEND symbolReference
{ Names_Check($2, $5);
if (($5) != NULL) free($5);
$$ = Construct(P_UNIONLIT, 2, $2, $3); }
;
enumeration :
KENUMERATION symbolDefinitionS KEND
{ $$ = Construct(P_ENUMLIT, 1, $2); }
;
export :
empty
| KEXPORT operationNameReferenceS
{ $$ = Construct(P_EXPORT, 2, $2, NULL); }
;
operationNameReferenceS :
operationNameReference
{ $$ = RCONS(NULL, $1); }
| operationNameReferenceS TCOMMA operationNameReference
{ $$ = RCONS($1, $3); }
;
symbolDefinitionS :
symbolDefinition
{ $$ = RCONS(NULL, $1); }
| symbolDefinitionS TCOMMA symbolDefinition
{ $$ = RCONS($1, $3); }
;
symbolReferenceS :
symbolReference
{ $$ = RCONS(NULL, $1); }
| symbolReferenceS TCOMMA symbolReference
{ $$ = RCONS($1, $3); }
;
operationSignatureS :
empty
| operationSignatureS operationSignature
{ $$ = RCONS($1, $2); }
;
operationSignature :
operationKind operationNameDefinition parameterClause returnClause whereClause
{ $$ = Construct(P_OPSIG, 4, $2, $3, $4, $5);
($$)->b.opsig.isFunction = ((int)($1) == KFUNCTION); }
;
operationKind :
KOPERATION
| KOP
| KFUNCTION
;
parameterClause :
empty
| TLSQUARE TRSQUARE
{ $$ = NULL; }
| TLSQUARE parameterS TRSQUARE
{ $$ = $2; }
;
parameterS :
parameter
{ $$ = RCONS(NULL, $1); }
| parameterS TCOMMA parameter
{ $$ = RCONS($1, $3); }
;
parameterFirstExpression :
expression
{
$$ = Construct(P_PARAM, 3, $1, NULL, NULL);
}
| KATTACHED expression
{
$$ = Construct(P_PARAM, 3, $2, NULL, NULL);
($$)->b.param.isAttached = TRUE;
}
| KMOVE expression
{
$$ = Construct(P_PARAM, 3, $2, NULL, NULL);
($$)->b.param.move = TRUE;
}
| KATTACHED KMOVE expression
{
$$ = Construct(P_PARAM, 3, $3, NULL, NULL);
($$)->b.param.isAttached = ($$)->b.param.move = TRUE;
}
| KMOVE KATTACHED expression
{
$$ = Construct(P_PARAM, 3, $3, NULL, NULL);
($$)->b.param.isAttached = ($$)->b.param.move = TRUE;
}
;
parameter :
parameterFirstExpression
{
($1)->b.param.type = ($1)->b.param.sym;
($1)->b.param.sym = buildSymbol(P_SYMDEF, "@", nextPhoney++);
$$ = $1;
}
| parameterFirstExpression TCOLON expression
{
if (($1)->b.param.sym->tag == P_SYMREF) ($1)->b.param.sym->tag = P_SYMDEF;
else {
BeginSyntaxErrorMessage();
ErrorWrite("Expected identifier, found expression");
EndErrorMessage();
($1)->b.param.sym = buildSymbol(P_SYMDEF, "@", nextPhoney++);
}
($1)->b.param.type = $3;
$$ = $1;
}
;
returnClause :
empty
| ORETURNS TLSQUARE TRSQUARE
{ $$ = NULL; }
| ORETURNS TLSQUARE parameterS TRSQUARE
{ $$ = $3; }
;
whereClause :
empty
| KWHERE whereWidgitS KEND KWHERE
{ $$ = $2; }
;
whereWidgitS :
whereWidgit
{ $$ = RCONS(NULL, $1); }
| whereWidgitS whereWidgit
{ $$ = RCONS($1, $2); }
;
whereWidgit :
symbolDefinition whereOperator expression
{ $$ = Construct(P_WHEREWIDGIT, 3, $1, $2, $3);
if (($$)->b.wherewidgit.op == OASSIGN) ($$)->b.wherewidgit.op = OIDENTITY;
if ((int)$2==OCONFORMSTO) ($1)->tag = P_SYMREF; }
;
whereOperator :
OIDENTITY
| OASSIGN
| OCONFORMSTO
;
object :
KOBJECT symbolDefinition export declarationS monitoredPart operationDefinitionS processDefinition KEND symbolReference
{ Names_Check($2, $9);
if (($9) != NULL) free($9);
$$ = Construct(P_OBLIT, 10,
buildString(currentFileName), NULL, $2, NULL, NULL,
$3, $4 ,$5, $6, $7); }
;
declarationS :
empty
| declarationS declaration
{ $$ = RAPPEND($1, $2); }
;
declaration :
/* $$ = $1 */
constantDeclaration
| variableDeclaration
| error
;
constantDefOp :
OIDENTITY
| OASSIGN
;
constantDeclaration :
KCONST symbolDefinition typeClauseOpt constantDefOp expression
{ $$ = Construct(P_CONSTDECL, 3, $2, $3, $5); }
| KATTACHED KCONST symbolDefinition typeClauseOpt constantDefOp expression
{ $$ = Construct(P_CONSTDECL, 3, $3, $4, $6);
($$)->b.constdecl.isAttached = TRUE; }
;
initializerOpt :
empty
| OASSIGN expression
{ $$ = $2; }
;
initializer :
OASSIGN expression
{ $$ = $2; }
;
variableDeclaration :
KVAR symbolDefinitionS typeClause initializerOpt
{ $$ = Distribute(P_VARDECL, $2, 2, $3, $4); }
| KATTACHED KVAR symbolDefinitionS typeClause initializerOpt
{ $$ = Distribute(P_VARDECL, $3, 2, $4, $5);
{
register NodePtr q;
if (($$)->tag == T_SEQUENCE) {
Sequence_For(q, ($$))
q->b.vardecl.isAttached = TRUE;
Sequence_Next
} else {
($$)->b.vardecl.isAttached = TRUE;
}
}
}
;
monitoredPart :
empty
| KMONITOR declarationS operationDefinitionS initiallyDefinition recoveryDefinition KEND KMONITOR
{ $$ = Construct(P_MONITOR, 4, $2, $3, $4, $5); }
| KINITIALLY blockBody KEND KINITIALLY
{
$$ = Construct(P_INITDEF, 1, $2);
$$ = Construct(P_MONITOR, 4, NULL, NULL, $$, NULL);
($$)->b.monitor.mayBeElided = TRUE;
}
;
operationDefinitionS :
empty
| operationDefinitionS operationDefinition
{ $$ = RCONS($1, $2); }
;
private :
KPRIVATE
| empty
;
operationDefinition :
private operationSignature blockBody KEND operationNameReference
{ Names_Check(($2)->b.opsig.name, $5);
if (($5) != NULL) free($5);
$$ = Construct(P_OPDEF, 2, $2, $3);
if ($1 != NULL) ($$)->b.opdef.isPrivate = TRUE; }
;
blockBody :
declarationsAndStatements unavailableHandler failureHandler
{ $$ = Construct(P_BLOCK, 3, $1, $2, $3); }
;
initiallyDefinition :
empty
| KINITIALLY blockBody KEND KINITIALLY
{ $$ = Construct(P_INITDEF, 1, $2); }
;
recoveryDefinition :
empty
| KRECOVERY blockBody KEND KRECOVERY
{ $$ = Construct(P_RECOVERYDEF, 1, $2); }
;
processDefinition :
empty
| KPROCESS blockBody KEND KPROCESS
{ $$ = Construct(P_PROCESSDEF, 1, $2); }
;
declarationsAndStatements :
declarationS statementS
{ $$ = RAPPEND($1, $2); }
;
statementS :
empty
| statementS statement
{ $$ = RCONS($1, $2); }
;
statement :
ifStatement
| loopStatement
| forStatement
| exitStatement
| assignmentOrInvocationStatement
| assertStatement
| fixStatement
| refixStatement
| unfixStatement
| moveStatement
| compoundStatement
| primitiveStatement
| waitStatement
| signalStatement
| checkpointStatement
| returnStatement
| returnAndFailStatement
| error
;
optDeclaration :
empty
| symbolDefinition typeClause
{ $$ = Construct(P_VARDECL, 3, $1, $2, NULL); }
;
unavailableHandler :
empty
| KWHEN optDeclaration KUNAVAILABLE blockBody KEND KUNAVAILABLE
{ $$ = Construct(P_UNAVAILABLEHANDLER, 2, $2, $4); }
;
failureHandler :
empty
| KON KFAILURE blockBody KEND KFAILURE
{ $$ = Construct(P_FAILUREHANDLER, 1, $3); }
;
ifClauseS :
ifClause
{ $$ = RCONS(NULL, $1); }
| ifClauseS KELSEIF ifClause
{ $$ = RCONS($1, $3); }
;
ifClause :
expression KTHEN declarationsAndStatements
{ $$ = Construct(P_IFCLAUSE, 2, $1, $3); }
;
elseClause :
empty
| KELSE declarationsAndStatements
{ $$ = Construct(P_ELSECLAUSE, 1, $2); }
;
ifStatement :
KIF ifClauseS elseClause KEND KIF
{ $$ = Construct(P_IFSTAT, 2, $2, $3); }
;
forStatement :
KFOR TLPAREN assignmentOrInvocationStatement TCOLON expression TCOLON assignmentOrInvocationStatement TRPAREN statementS KEND KFOR
{ $$ = Construct(P_INVOC, 3, $5, makeOpName(ONOT), NULL);
$$ = Construct(P_EXITSTAT, 1, $$);
$$ = RCONS(NULL, $$);
$$ = RAPPEND($$, $9);
$$ = RCONS($$, $7);
$$ = Construct(P_LOOPSTAT, 1, $$);
$$ = RCONS(RCONS(NULL, $3), $$);
$$ = Construct(P_BLOCK, 3, $$, NULL, NULL);
}
| KFOR symbolDefinition typeClause initializer KWHILE expression KBY assignmentOrInvocationStatement statementS KEND KFOR
{ $$ = Construct(P_INVOC, 3, $6, makeOpName(ONOT), NULL);
$$ = Construct(P_EXITSTAT, 1, $$);
$$ = RCONS(NULL, $$);
$$ = RAPPEND($$, $9);
$$ = RCONS($$, $8);
$$ = Construct(P_LOOPSTAT, 1, $$);
$$ = RCONS(RCONS(NULL, Construct(P_VARDECL, 3, $2, $3, $4)), $$);
$$ = Construct(P_BLOCK, 3, $$, NULL, NULL);
}
;
loopStatement :
KLOOP declarationsAndStatements KEND KLOOP
{ $$ = Construct(P_LOOPSTAT, 1, $2); }
;
exitStatement :
KEXIT whenClause
{ $$ = Construct(P_EXITSTAT, 1, $2); }
;
whenClause :
empty
| KWHEN expression
{ $$ = $2; }
;
assignmentOrInvocationStatement :
expressionS
{ if (($1)->nChildren > 1) {
BeginSyntaxErrorMessage();
ErrorWrite("Found expressionS where expression expected");
EndErrorMessage();
($1)->nChildren = 1;
}
$$ = Construct(P_ASSIGNSTAT, 3, NULL, OASSIGN, $1);
}
| expressionS assignmentOp expressionS
{ $$ = Construct(P_ASSIGNSTAT, 3, $1, $2, $3); }
;
assignmentOp :
OASSIGN
| TSUGARASSIGN
;
assertStatement :
KASSERT expression
{ $$ = Construct(P_ASSERTSTAT, 1, $2); }
;
fixStatement :
KFIX expression KAT expression
{ $$ = Construct(P_FIXSTAT, 2, $2, $4); }
;
refixStatement :
KREFIX expression KAT expression
{ $$ = Construct(P_REFIXSTAT, 2, $2, $4); }
;
unfixStatement :
KUNFIX expression
{ $$ = Construct(P_UNFIXSTAT, 1, $2); }
;
moveStatement :
KMOVE expression KTO expression
{ $$ = Construct(P_MOVESTAT, 2, $2, $4); }
;
compoundStatement :
KBEGIN blockBody KEND
{ $$ = $2; }
;
checkpoint :
KCONFIRM
| KCONFIRM KCHECKPOINT
{ $$ = $1; }
| KCHECKPOINT
;
checkpointStatement :
checkpoint
{ $$ = Construct(P_CHECKPOINTSTAT, 2, (NodePtr)T_NONE, NULL);
($$)->b.checkpointstat.confirm = ( ($1) == (NodePtr)KCONFIRM); }
| checkpoint KTO expression
{ $$ = Construct(P_CHECKPOINTSTAT, 2, $2, $3);
($$)->b.checkpointstat.confirm = ( ($1) == (NodePtr)KCONFIRM); }
| checkpoint KAT expression
{ $$ = Construct(P_CHECKPOINTSTAT, 2, $2, $3);
($$)->b.checkpointstat.confirm = ( ($1) == (NodePtr)KCONFIRM); }
| checkpoint KAT KALL
{ $$ = Construct(P_CHECKPOINTSTAT, 2, $2, $3);
($$)->b.checkpointstat.confirm = ( ($1) == (NodePtr)KCONFIRM); }
;
returnStatement :
KRETURN
{ $$ = Construct(P_RETURNSTAT, 0); }
;
returnAndFailStatement :
KRETURNANDFAIL
{ $$ = Construct(P_RETURNANDFAILSTAT, 0); }
;
primitiveImplementation :
TINTEGERLITERAL
{ $$ = Construct(P_INTLIT, 0);
($$)->b.intlit.string = ($1)->b.string.string; }
| TSTRINGLITERAL
{ $$ = Construct(P_STRINGLIT, 0);
($$)->b.intlit.string = ($1)->b.string.string; }
;
primitiveStatement :
KPRIMITIVE primitiveImplementation TLSQUARE symbolReferenceSopt TRSQUARE OASSIGN TLSQUARE symbolReferenceSopt TRSQUARE
{ $$ = Construct(P_PRIMSTAT, 3, $2, $4, $8); }
;
symbolReferenceSopt :
empty
| symbolReferenceS
;
waitStatement :
KWAIT expression
{ $$ = Construct(P_WAITSTAT, 1, $2); }
;
signalStatement :
KSIGNAL expression
{ $$ = Construct(P_SIGNALSTAT, 1, $2); }
;
expressionS :
expression
{ $$ = RCONS(NULL, $1); }
| expressionS TCOMMA expression
{ $$ = RCONS($1, $3); }
;
expression :
expressionZero
| expression OOR expression
{ $$ = Construct(P_INVOC, 3, $1, makeOpName($2), singleArg($3)); }
| expression KOR expression
{ $$ = Construct(P_EXP, 3, $1, $2, $3); }
| expression OAND expression
{ $$ = Construct(P_INVOC, 3, $1, makeOpName($2), singleArg($3)); }
| expression KAND expression
{ $$ = Construct(P_EXP, 3, $1, $2, $3); }
| ONOT expression
{ $$ = Construct(P_INVOC, 3, $2, makeOpName($1), NULL); }
| expression OIDENTITY expression
{ $$ = Construct(P_EXP, 3, $1, $2, $3); }
| expression ONOTIDENTITY expression
{ $$ = Construct(P_EXP, 3, $1, $2, $3); }
| expression OEQUAL expression
{ $$ = Construct(P_INVOC, 3, $1, makeOpName($2), singleArg($3)); }
| expression ONOTEQUAL expression
{ $$ = Construct(P_INVOC, 3, $1, makeOpName($2), singleArg($3)); }
| expression OGREATER expression
{ $$ = Construct(P_INVOC, 3, $1, makeOpName($2), singleArg($3)); }
| expression OLESS expression
{ $$ = Construct(P_INVOC, 3, $1, makeOpName($2), singleArg($3)); }
| expression OGREATEREQUAL expression
{ $$ = Construct(P_INVOC, 3, $1, makeOpName($2), singleArg($3)); }
| expression OLESSEQUAL expression
{ $$ = Construct(P_INVOC, 3, $1, makeOpName($2), singleArg($3)); }
| expression OCONFORMSTO expression
{ $$ = Construct(P_EXP, 3, $1, $2, $3); }
| KVIEW expression KAS expression
{ $$ = Construct(P_VIEW, 2, $2, $4); }
| KRESTRICT expression KTO expression
{ $$ = Construct(P_RESTRICT, 2, $2, $4); }
| expression OPLUS expression
{ $$ = Construct(P_INVOC, 3, $1, makeOpName($2), singleArg($3)); }
| expression OMINUS expression
{ $$ = Construct(P_INVOC, 3, $1, makeOpName($2), singleArg($3)); }
| expression OTIMES expression
{ $$ = Construct(P_INVOC, 3, $1, makeOpName($2), singleArg($3)); }
| expression ODIVIDE expression
{ $$ = Construct(P_INVOC, 3, $1, makeOpName($2), singleArg($3)); }
| expression OMOD expression
{ $$ = Construct(P_INVOC, 3, $1, makeOpName($2), singleArg($3)); }
| expression TOPERATOR expression
{ $$ = Construct(P_INVOC, 3, $1, makeOpName($2), singleArg($3)); }
| ONEGATE expression
{ if (($2)->tag == P_INTLIT) {
char *old, *new;
old = ($2)->b.stringlit.string;
new = (char *)malloc(strlen(old) + 2);
if (*old == '-') {
strcpy(new, old+1);
} else {
strcpy(new, "-");
strcat(new, old);
}
($2)->b.stringlit.string = new;
free(old);
$$ = $2;
} else {
$$ = Construct(P_INVOC, 3, $2, makeOpName($1), NULL);
}
}
| KISFIXED expression
{ $$ = Construct(P_UNARYEXP, 2, $1, $2); }
| KLOCATE expression
{ $$ = Construct(P_UNARYEXP, 2, $1, $2); }
| KAWAITING expression
{ $$ = Construct(P_UNARYEXP, 2, $1, $2); }
;
expressionZero :
invocation
| expressionZero TDOLLAR TIDENTIFIER
{ $$ = Construct(P_FIELDSEL, 2, $1, $3); }
| expressionZero TLPAREN argumentS TRPAREN
{ $$ = Construct(P_SUBSCRIPT, 2, $1, $3); }
;
invocation :
primary
| identifierOperationNameReference TLSQUARE TRSQUARE
{ $$ = Construct(P_INVOC, 3, Construct(P_SELFLIT, 0), $1, NULL); }
| identifierOperationNameReference TLSQUARE argumentS TRSQUARE
{ $$ = Construct(P_INVOC, 3, Construct(P_SELFLIT, 0), $1, $3); }
| expressionZero TDOT operationNameReference argumentClause
{ $$ = Construct(P_INVOC, 3, $1, $3, $4); }
;
primary :
literal
| symbolReference
| TLPAREN expression TRPAREN
{ $$ = $2; }
;
operationNameDefinition :
operationName
| operatorName
| definableOperatorName
{ $$ = makeOpName($1); }
;
operatorName :
TOPERATOR
{ $$ = makeOpName($1); }
;
operationName :
TIDENTIFIER
{ $$ = makeOpName($1); }
;
definableOperatorName :
OOR
| OAND
| OEQUAL
| ONOTEQUAL
| OGREATER
| OLESS
| OGREATEREQUAL
| OLESSEQUAL
| ONEGATE
| ONOT
| OPLUS
| OMINUS
| OTIMES
| ODIVIDE
| OMOD
;
nondefinableOperatorName :
OIDENTITY
| ONOTIDENTITY
| OCONFORMSTO
;
operationNameReference :
operatorName
| definableOperatorName
{ $$ = makeOpName($1); }
| nondefinableOperatorName
{ $$ = makeOpName($1); }
| operationName
| nondefinableOperationName
{ $$ = makeOpName($1); }
;
identifierOperationNameReference :
operationName
| nondefinableOperationName
{ $$ = makeOpName($1); }
;
nondefinableOperationName :
KOWNTYPE
| KOWNNAME
;
argumentClause :
empty
| TLSQUARE TRSQUARE
{ $$ = NULL; }
| TLSQUARE argumentS TRSQUARE
{ $$ = $2; }
;
argumentS :
argument
{ $$ = RCONS(NULL, $1); }
| argumentS TCOMMA argument
{ $$ = RCONS($1, $3); }
;
argument :
expression
{ $$ = Construct(P_ARG, 1, $1); }
| KMOVE expression
{ $$ = Construct(P_ARG, 1, $2);
($$)->b.arg.move = 1; }
| KVISIT expression
{ $$ = Construct(P_ARG, 1, $2);
($$)->b.arg.visit = 1; }
;
literal :
TSTRINGLITERAL
{ $$ = Construct(P_STRINGLIT, 0);
($$)->b.stringlit.string = ($1)->b.string.string;
free((char *) ($1)); }
| TCHARACTERLITERAL
{ $$ = Construct(P_CHARLIT, 0);
($$)->b.stringlit.string = ($1)->b.string.string;
free((char *) ($1)); }
| TINTEGERLITERAL
{ $$ = Construct(P_INTLIT, 0);
($$)->b.stringlit.string = ($1)->b.string.string;
free((char *) ($1)); }
| TREALLITERAL
{ $$ = Construct(P_REALLIT, 0);
($$)->b.stringlit.string = ($1)->b.string.string;
free((char *) ($1)); }
| KTRUE
{ $$ = Construct(P_BOOLLIT, 0);
($$)->b.boollit.value = 1; }
| KFALSE
{ $$ = Construct(P_BOOLLIT, 0);
($$)->b.boollit.value = 0; }
| KSELF
{ $$ = Construct(P_SELFLIT, 0); }
| KNIL
{ $$ = Construct(P_NILLIT, 0); }
| builtinType
{ $$ = Construct(P_BUILTINLIT, 0);
($$)->b.builtinlit.whichType = (int) $1; }
| typeLiteral
| vectorLiteral
;
vectorLiteral :
TLCURLY expressionSOpt typeClauseOpt TRCURLY
{ $$ = Construct(P_VECTORLIT, 3, $3, $2, NULL); }
;
expressionSOpt :
empty
| expressionS
;
typeLiteral :
typeRest
{ ($1)->b.oblit.f.immutable = 0; $$ = $1; }
| KIMMUTABLE typeRest
{ ($2)->b.oblit.f.immutable = 1; $$ = $2; }
;
typeRest :
/* { $$ = $1 } for all cases */
abstractType
| object
| record
| union
| enumeration
;
symbolReference :
TIDENTIFIER
{ $$ = Construct (P_SYMREF, 0);
($$)->b.symref.ident = ($1)->b.ident.ident;
free ($1); }
;
symbolDefinition :
TIDENTIFIER
{ $$ = Construct (P_SYMDEF, 0);
($$)->b.symdef.ident = ($1)->b.ident.ident;
free($1); }
;
%%